' *** FFT11.01A - Q (=2^N) POINT FFT (POSITIVE FREQUENCIES ONLY) ***

' ILLUSTRATE OVERSAMPLING ALSO SEE FFT11.02

10 SCREEN 9, 1: COLOR 15, 1: CLS 'SETUP DISPLAY SCREEN

PRINT "THIS PROGRAM ILLUSTRATES 16:1 OVERSAMPLING.  BEST ILLUSTRATION IS"

PRINT "WITH N=5 (Q^N = 32) AND F=15.  GENERATE SINUSOID AND RECONSTRUCT TO SEE"

PRINT "THE INTERMODULATION DISTORTION.  GENERATE SINUSOID AGAIN (F = 15 AGAIN)"

PRINT "THEN SELECT THE 'OVERSAMPLE' OPTION FROM THE MAIN MENU.  RECONSTRUCT"

PRINT "THIS OVERSAMPLED WAVEFORM AND VIEW THE RESULTS."

PRINT

INPUT "ENTER TO CONTINUE"; A$

12 CLS : PRINT "INPUT NUMBER OF DATA POINTS AS 2^N. "

14 INPUT "N = "; N

16 Q = 2 ^ N

20 Q2 = Q / 2: Q3 = Q2 - 1: Q4 = Q / 4: Q5 = Q4 - 1: Q8 = Q / 8

22 DIM C(2, 16 * Q), S(2, 16 * Q), KC(8 * Q), KS(8 * Q)'DIM DATA AND TWIDDLE FACTORS

30 PI = 3.141592653589793#: P2 = 2 * PI: K1 = P2 / Q

REM ***  GENERATE TWIDDLE FACTORS  ****

32 FOR I = 0 TO Q2: KC(I) = COS(K1 * I): KS(I) = SIN(K1 * I): NEXT

34 IOFLG = 2' SET OUTPUT TO GRAPHIC DISPLAY

40 CLS ' DISPLAY MAIN MENU

50 PRINT SPC(30); "MAIN MENU": PRINT : PRINT

60 PRINT SPC(5); "1 = ANALYZE SINE FUNCTION": PRINT

62 PRINT SPC(5); "2 = INVERSE TRANSFORM": PRINT

64 PRINT SPC(5); "3 = SETUP DISPLAY": PRINT

65 PRINT SPC(5); "4 = OVERSAMPLE DATA": PRINT

66 PRINT SPC(5); "5 = EXIT": PRINT

70 PRINT SPC(10); "MAKE SELECTION :";

80 A$ = INKEY$: IF A$ = "" THEN 80

90 A = VAL(A$): ON A GOSUB 600, 200, 800, 700, 990

95 GOTO 40



100 REM *** FFT ***

102 T9 = TIMER

104 REM                *** STAGE A ***

106 FOR I = 0 TO Q2 - 1: I2 = 2 * I

108 C(1, I2) = (C(0, I) + C(0, Q2 + I)) / 2

110 C(1, I2 + 1) = (C(0, I) - C(0, Q2 + I)) / 2

112 NEXT I

114 REM                *** STAGE B ***

116 FOR I = 0 TO Q2 - 1 STEP 2: I2 = 2 * I: IQ2 = I + Q2

118 C(0, I2) = (C(1, I) + C(1, IQ2)) / 2

120 C(0, I2 + 1) = (C(1, I + 1)) / 2: S(0, I2 + 1) = (C(1, IQ2 + 1)) / 2

122 C(0, I2 + 2) = (C(1, I) - C(1, IQ2)) / 2

124 NEXT I

126 T1 = 1: T0 = 0

130 REM                *** REMAINING STAGES ***

132 FOR M = 2 TO N - 1: QT = 2 ^ (M - 1)

134 QT2 = 2 * QT: KT1 = 2 ^ (N - M - 1)

136 FOR I = 0 TO Q3 STEP QT2: J1 = 2 * I: K = I + Q2

138 REM * COMPUTE DIRECT COMPONENTS *

140 FOR J = 0 TO QT: KT = J * KT1: KJ = K + J

142 C(T1, J1 + J) = .5 * (C(T0, I + J) + C(T0, KJ) * KC(KT) - S(T0, KJ) * KS(KT))

144 S(T1, J1 + J) = .5 * (S(T0, I + J) + C(T0, KJ) * KS(KT) + S(T0, KJ) * KC(KT))

146 NEXT J

150 REM * COMPUTE LATENT COMPONENTS *

152 FOR J = QT + 1 TO QT2: KT = J * KT1: KJ = K + QT2 - J

154 C(T1, J1 + J) = .5 * (C(T0, I + QT2 - J) + C(T0, KJ) * KC(KT) + S(T0, KJ) * KS(KT))

156 S(T1, J1 + J) = .5 * (-S(T0, I + QT2 - J) + C(T0, KJ) * KS(KT) - S(T0, KJ) * KC(KT))

158 NEXT J

160 NEXT I

162 T0 = 1 - T0: T1 = 1 - T0

164 NEXT M



166 T9 = TIMER - T9

170 T0 = 1 - T0: T1 = 1 - T0

172 ON IOFLG GOSUB 300, 350

174 LOCATE 23, 20

176 PRINT : PRINT : INPUT "C/R TO CONTINUE:"; A$

178 RETURN



REM ****************************************************

199 REM *              INVERSE TRANSFORM               *

REM ****************************************************

200 PRINT



202 REM INVERSE TRANSFORM ROUTINE

204 FOR M = N - 1 TO 0 STEP -1' LOOP FOR STAGES OF COMPUTATION

206 QT2 = 2 ^ (M): QT = INT(QT2 / 2): QT4 = 2 * QT2: KT1 = 2 ^ (N - M - 1)

208  FOR I = 0 TO Q - (QT2) STEP QT4

210   FOR J = 0 TO QT: KI = J + (I / 2): KT = J * KT1: KJ = Q2 + KI

212   MCT = C(T1, J + I) - C(T1, I + QT2 - J): MST = S(T1, J + I) + S(T1, I + QT2 - J)

214   C(T0, KJ) = MCT * KC(KT) + MST * KS(KT)

216   S(T0, KJ) = MST * KC(KT) - MCT * KS(KT)

218   C(T0, KI) = (2 * C(T1, J + I)) - C(T0, KJ) * KC(KT) + S(T0, KJ) * KS(KT)

220   S(T0, KI) = (2 * S(T1, J + I)) - C(T0, KJ) * KS(KT) - S(T0, KJ) * KC(KT)

222  NEXT J

224 NEXT I

226 T0 = 1 - T0: T1 = 1 - T0

228 NEXT M

298 GOSUB 370 ' PLOT DATA

INPUT "C/R TO CONTINUE"; A$

RETURN

STOP



REM *******************************************************

REM *               DATA OUTPUT ROUTINES                  *

REM *******************************************************

300 REM **** PRINT OUTPUT DATA ****

302 CLS : PRINT "FREQ     F(COS)       F(SIN)       "'PRINT HEADING

304 PRINT : PRINT

306 FOR Z = 0 TO Q4

308 GOSUB 320' PRINT DATA

310 LCTR = LCTR + 1: IF LCTR = 20 THEN LCTR = 0: INPUT A$

312 NEXT Z

314 PRINT : PRINT "TIME ="; T9

316 LCTR = 0

318 RETURN

320 PRINT USING "###_    "; Z; :

322 PRINT USING "+##.#####_    "; C(T1, Z); S(T1, Z);

324 PRINT USING "###_    "; Z + Q4; :

326 PRINT USING "+##.#####_    "; C(T1, Z + Q4); S(T1, Z + Q4)

330 RETURN



349 REM ******  PLOT DATA ******

350 CLS : X0 = 50: Y0 = 300: XSF = 500 / Q2: YSF = 300

352 LINE (X0 - 1, 50)-(X0 - 1, Y0)' DRAW Y AXIS

354 LINE (X0, Y0)-(X0 + 500, Y0)' DRAW X AXIS

356 LINE (X0, Y0)-(X0, Y0)' SET PEN TO ORIGIN

358 FOR I = 0 TO Q2

360 YP = SQR(C(T1, I) ^ 2 + S(T1, I) ^ 2)' FIND RSS OF DATA POINT

362 LINE (X0 + XSF * I, Y0 - YSF * YP)-(X0 + XSF * I, Y0 - YSF * YP)' DRAW POINT

364 NEXT I

366 RETURN

368 REM *****   PLOT RECONSTRUCTED DATA   *********

370 CLS : X0 = 50: Y0 = 170: XSF = 500 / Q: YSF = 100

372 LINE (X0 - 1, 50)-(X0 - 1, (2 * (Y0 - 50)) + 50)' DRAW Y AXIS

374 LINE (X0, Y0)-(X0 + 500, Y0)' DRAW X AXIS

376 LINE (X0, Y0)-(X0, Y0)' SET PEN TO ORIGIN

378 FOR I = 0 TO Q

380 YP = C(T1, I)' FIND DATA POINT

382 LINE (X0 + XSF * I, Y0 - YSF * YP)-(X0 + XSF * I, Y0 - YSF * YP)' DRAW POINT

384 NEXT I

386 RETURN





400 REM GENERATE SINEWAVE FUNCTION

410 FOR I = 0 TO Q

416 C(0, I) = COS(F9 * K1 * I): S(0, I) = 0

422 C(1, I) = 0: S(1, I) = 0

430 NEXT

440 RETURN



600 CLS : PRINT : PRINT : REM * GENERATE COSINE COMPONENT *

602 INPUT "PLEASE SPECIFY FREQUENCY "; F9

604 PRINT "PREPARING DATA INPUT - PLEASE WAIT!"

610 GOSUB 400 ' GENERATE COSINE WAVE

612 T0 = 1: T1 = 0

614 REM PRINT : INPUT "DATA READY - C/R TO CONTINUE"; A$

620 GOSUB 100 ' PERFORM PFFFT

630 RETURN



700 REM *** 8X OVERSAMPLE DATA ***

702 FOR I = Q2 TO Q ' CLEAR UPPER ARRAY

704 C(T1, I) = 0: S(T1, I) = 0

706 NEXT I

710 N = N + 4 ' INCREASE 2^N EXPONENT

714 Q = 2 ^ N ' INCREASE Q & GEN NEW CONSTANTS

716 Q2 = Q / 2: Q3 = Q2 - 1: Q4 = Q / 4: Q5 = Q4 - 1: Q8 = Q / 8

718 K1 = P2 / Q

719 ' ***  GENERATE NEW TWIDDLE FACTORS  ****

720 FOR I = 0 TO Q2: KC(I) = COS(K1 * I): KS(I) = SIN(K1 * I): NEXT



722 GOSUB 350 ' PLOT OVERSAMPLED DATA

724 INPUT A$ ' WAIT USER - DATA IS NOW OVERSAMPLED

726 RETURN



800 REM ***  SETUP PRINTOUT/GRAPHIC DISPLAY  ***

802 CLS ' CLEAR SCREEN

804 INPUT "GRAPHIC DISPLAY (Y/N)"; A$

806 IF A$ = "Y" THEN IOFLG = 2 ELSE IOFLG = 1

808 RETURN



990 END: STOP



